package com.remote.common;

import com.remote.common.command.Commands;
import com.remote.common.command.handler.ICommandHandler;
import com.remote.common.exception.RemoteException;
import com.remote.common.model.ServerClientInfo;
import io.netty.util.internal.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

public class DefaultRemoteFactory implements RemoteFactory {
    /**
     * logger
     */
    protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultRemoteFactory.class);

    protected Map<Enum<Commands>, ICommandHandler> commandHandlerMap = new ConcurrentHashMap<>();
    protected Map<String, ServerClientInfo> clientMap = new ConcurrentHashMap<>();
    private RemoteConfiguration remoteConfiguration;
    private ScheduledExecutorService scheduledExecutorService;


    public DefaultRemoteFactory(RemoteConfiguration remoteConfiguration) {
        this.remoteConfiguration = remoteConfiguration;
        this.scheduledExecutorService = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1);
    }

    @Override
    public void setScheduledExecutorService(ScheduledExecutorService scheduledExecutorService) {
        this.scheduledExecutorService = scheduledExecutorService;
    }

    @Override
    public void registerHandler(Enum<Commands> commandsEnum, ICommandHandler commandHandler) {
        commandHandlerMap.put(commandsEnum, commandHandler);
    }

    @Override
    public void addClient(ServerClientInfo clientInfo) throws RemoteException {
        clientMap.put(clientInfo.getClientInfo().getClientId(), clientInfo);
    }

    @Override
    public ServerClientInfo getClient(String clientId) throws RemoteException {
        return clientMap.get(clientId);
    }

    @Override
    public boolean hasClient(String controlClient) {
        if (StringUtil.isNullOrEmpty(controlClient)) {
            return false;
        }
        return clientMap.containsKey(controlClient);
    }


    @Override
    public void removeClient(String controlClient) {
        clientMap.remove(controlClient);
    }

    @Override
    public ICommandHandler getCommandHandler(Enum<Commands> commandsEnum) {
        return commandHandlerMap.get(commandsEnum);
    }

    @Override
    public String generateClientId() {
        String id = "";
        while (StringUtil.isNullOrEmpty(id) && !clientMap.containsKey(id)) {
            id = String.valueOf(new Random().nextInt(1000000000));
        }
        return id;
    }

    @Override
    public RemoteConfiguration getRemoteConfiguration() {
        return remoteConfiguration;
    }


}
